#include <iostream>
#include <string>
#include <list>

using namespace std;

// virtual observer
class VObserver
{
public:
    virtual void OnExec(float temperatrue) = 0;
};

// virtual subject
class VSubject
{
public:
    virtual void AddListener(VObserver *ob) = 0;
    virtual void RemoveListener(VObserver *ob) = 0;
    virtual void Notify() = 0;
};


class Subject : public VSubject
{
private:
    list<VObserver*> m_ob_list;
    float m_temperature;
public:
    Subject();
    void AddListener(VObserver *ob);
    void RemoveListener(VObserver *ob);
    void Notify();
    void Change(float temperatrue);
};

Subject::Subject()
{
    m_ob_list.clear();
    m_temperature = 36.5;
}

void Subject::AddListener(VObserver *ob)
{
    m_ob_list.push_back(ob);
}

void Subject::RemoveListener(VObserver *ob)
{
    m_ob_list.remove(ob);
}

void Subject::Notify()
{
    for (list<VObserver*>::iterator it = m_ob_list.begin(); it != m_ob_list.end(); it++)
    {
        (*it)->OnExec(m_temperature);
    }
}

void Subject::Change(float temperatrue)
{
    m_temperature = temperatrue;
    Notify();
}

class Observer : public VObserver
{
private:
    string m_name;
    float m_temperatrue;

public:
    Observer(const string & name);
    void OnExec(float temperatrue);
};

Observer::Observer(const string & name)
{
    m_name = name;
}

void Observer::OnExec(float temperatrue)
{
    m_temperatrue = temperatrue;
    cout << "observer " << m_name << " get temperature " << m_temperatrue << "!!" << endl;
}



int main()
{
    Observer ob1("xiao");
    Observer ob2("fan");

    Subject s;
    s.AddListener(&ob1);
    s.AddListener(&ob2);
    s.Change(2);

    s.RemoveListener(&ob2);
    s.Change(3);

    return 0;
}